package com.onlyxiahui.framework.action.dispatcher.general.extend.impl.handler;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONPath;
import com.onlyxiahui.common.message.AbstractMessage;
import com.onlyxiahui.common.message.SkipMessage;
import com.onlyxiahui.common.message.base.ResultHead;
import com.onlyxiahui.common.message.bean.Info;
import com.onlyxiahui.common.message.node.Head;
import com.onlyxiahui.common.message.result.ResultBodyMessage;
import com.onlyxiahui.common.message.result.ResultMessage;
import com.onlyxiahui.common.message.util.HeadUtil;
import com.onlyxiahui.framework.action.dispatcher.extend.ArgumentBox;
import com.onlyxiahui.framework.action.dispatcher.general.constant.DataConstant;
import com.onlyxiahui.framework.action.dispatcher.general.util.ActionDispatcherJsonUtil;

/**
 * 
 * <br>
 * Date 2019-08-07 14:56:45<br>
 * 
 * @author XiaHui [onlovexiahui@qq.com]<br>
 * @since 1.0.0
 */

public class ResultDataHandler {

	public Object result(Object data, Object body, ArgumentBox argumentBox) {
		if (null == data) {
			Head head = getHead(argumentBox, body);
			ResultMessage m = new ResultMessage();
			m.setHead(head);
			data = m;
		} else if (data instanceof SkipMessage) {

		} else if (data instanceof AbstractMessage) {
			AbstractMessage<?> m = (AbstractMessage<?>) data;

			if (null == m.getHead()) {
				Head head = getHead(argumentBox, body);
				m.setHead(head);
			}

			if (m.getBody() instanceof Collection) {
				Map<String, Object> map = new HashMap<>(1);
				map.put("items", m.getBody());

				ResultBodyMessage<Map<String, Object>> rb = new ResultBodyMessage<>();
				rb.setHead(m.getHead());
				rb.setBody(map);
				data = rb;
			} else {
				data = m;
			}
		} else if (data instanceof Info) {
			Head head = getHead(argumentBox, body);
			ResultMessage m = new ResultMessage();
			m.setHead(head);
			m.setInfo((Info) data);
			data = m;
		} else if (data instanceof Map) {
			Head head = getHead(argumentBox, body);
			ResultBodyMessage<Object> m = new ResultBodyMessage<>();
			m.setHead(head);
			m.setBody(data);
			data = m;
		} else if (data instanceof Collection) {
			Map<String, Object> map = new HashMap<>(1);
			map.put("items", data);
			Head head = getHead(argumentBox, body);
			ResultBodyMessage<Object> m = new ResultBodyMessage<>();
			m.setHead(head);
			m.setBody(map);
			data = m;
		} else {
			Head head = getHead(argumentBox, body);
			ResultBodyMessage<Object> m = new ResultBodyMessage<>();
			m.setHead(head);
			m.setBody(data);
			data = m;
		}
		return data;
	}

	private Head getHead(ArgumentBox argumentBox, Object requestData) {
		ResultHead head = null != argumentBox ? argumentBox.get(ResultHead.class) : null;
		if (null == head) {
			JSONObject jsonObject = null != argumentBox ? argumentBox.get(JSONObject.class) : null;
			if (null != jsonObject) {
				boolean hasHead = jsonObject.containsKey(DataConstant.HEAD) && jsonObject.get(DataConstant.HEAD) instanceof JSONObject;
				if (hasHead) {
					JSONObject headJsonObject = jsonObject.getJSONObject(DataConstant.HEAD);
					head = HeadUtil.toHead(headJsonObject);
				}
			} else {
				String message = (requestData instanceof String) ? requestData.toString() : "";
				if (ActionDispatcherJsonUtil.maybeJson(message)) {
					Object o = JSONPath.read(message, DataConstant.HEAD);
					if (o instanceof JSONObject) {
						head = HeadUtil.toHead((JSONObject) o);
					}
				}
			}
		}
		if (null == head) {
			head = new ResultHead();
		}
		head.setTimestamp(System.currentTimeMillis());
		return head;
	}
}
